package de.fuberlin.inf.alp2;

import java.util.Arrays;
import java.util.List;

public class ArrayPolygon implements Polygon {
	Point[] points;
	int last;
	Rectangle plane;
	
	public ArrayPolygon() {
		this(99);
	}
	public ArrayPolygon(final int MAX){
		this.points = new Point[MAX];
		this.last = -1;
		this.plane = new Rectangle(new Point(100,100));
	}

	@Override
	public boolean addPoint(Point p) throws Exception {
		if ((p.getX() > this.plane.getUpperRight().getX()) ||
				(p.getY() > this.plane.getUpperRight().getY()))
			throw new Exception("Point could not be added - Polygon would " +
					"reach out of plane");
		this.last++;
		if (this.last == points.length)
		{
			this.last--;
			throw new Exception("Maximum number of points already reached.");
		}
		points[last] = p;
		return true;
	}

	@Override
	public Point center() throws Exception {
		if (!isPolygon())
			throw new Exception("The centroid could not be calculated, cause" +
					" the points do not form a polygon");
		int sumOfX = 0, sumOfY = 0;
		int size = last + 1;
		for (int i = 0; i <= last; i++) {
			sumOfX += points[i].getX();
			sumOfY += points[i].getY();
		}
		return new Point((sumOfX / size), (sumOfY / size));
	}

	@Override
	public boolean isPolygon() {
		if (last > 1)
		{
			double gradient = Point.getGradient(points[0], points[1]);
			for (int i = 2; i <= last; i++)
				if (gradient != Point.getGradient(points[0], points[i]))
					return true;
		}
		return false;
	}

	@Override
	public double perimeter() throws Exception {
		if (!isPolygon())
			throw new Exception("The perimeter could not be calculated, cause" +
					" the points do not form a polygon");
		double ret = 0.0;
		Point preCurrent = points[last];
		for (int i = 0; i <= last; i++) {
			ret += points[i].distance(preCurrent);
			preCurrent = points[i];
		}
		return ret;
	}

	@Override
	public void shift(int dx, int dy) throws Exception {
		Point[] shiftedPoints = new Point[points.length];
		for (int i = 0; i <= last; i++) {
			Point shiftedPoint = new Point(points[i]);
			shiftedPoint.translate(dx, dy);
			if ((shiftedPoint.getX() > this.plane.getUpperRight().getX()) ||
					(shiftedPoint.getY() > this.plane.getUpperRight().getY()))
				throw new Exception("Shift not allowed - Polygon would reach " +
						"out of plane");
			shiftedPoints[i] = shiftedPoint;
		}
		this.points = shiftedPoints;
	}
	@Override
	public List<Point> getPoints() {
		return Arrays.asList(Arrays.copyOf(this.points, this.last+1));
	}
}
